Inductive Automation
News Room

News / November 04, 2009

Did You Know? You Can Avoid Repetitive Design Using Indirect Binding and Window Parameters

Using parameterization and indirection in your screens is an important way to reduce the amount of repetitive design work required when creating a SCADA system. For example, suppose you have 35 valves that need to be monitored and controlled. By creating one valve control screen and re-using it 35 times, you save time creating your system and you'll save time in the future when you only have to update the single valve control screen. There are two concepts that are required to achieve this in FactoryPMI: indirect data binding and parameter passing.

Indirect Data Binding


Indirect data binding is most important concept to understand in FactoryPMI if you want to avoid a massively repetitive design. The idea here is that your data, whether it is in SQLTags or data in a SQL database, is organized in some predictable pattern. For example, if you had 35 valves's worth of tags in SQLTags, their tag paths would be predictable based upon the valve number, for example:
 Facility/Valves/ValveX/HOA Facility/Valves/ValveX/Flow Facility/Valves/ValveX/OpenPct 
... where "X" would be replaced with the numbers 1 through 35.

Once your data is organized in a predictable pattern, you can use indirect data binding. Indirect data binding is any data binding where the target of the binding changes based upon some parameter in the window. For example, all of the bindings to display and control the valve would dynamically point to any of the 35 valves based upon a single parameter. If you're unfamiliar with FactoryPMI's data binding, you might want to review the topic in the user manual or the online training videos under "P.B.E." (Properties, Bindings, and Expressions).

The first and easiest way to use indirection is to use the indirect tag binding. The first step is to have some value that you'll use as the indirection parameter. Usually this would be a dynamic property, often placed on the Root Container of a Window. Let's call it "ValveNumber." Then create the display/control screen for the valve, but instead of using standard tag bindings for your components, use the indirect tag binding. Browse for the appropriate tag from any valve, highlight the valve number in the path, and click on the "Insert Property Value" button. Choose your ValveNumber parameter. Now your binding will point to whichever tag is indicated by the value of ValveNumber.

The second kind of indirection is through the expression binding. This is an extremely versatile binding type. In particular, there is the tag() expression, which will return the value of a tag path. The tag path itself can be constructed using other expressions, which can easily be indirect. For example, if we wanted to bind to the valves' "OpenPct" tag and also multiply by 100, we could use an expression like:
 tag(    "Facility/Valves/Valve" +     {Root Container.ValveNumber} +     "/OpenPct"    ) * 100.0 
Lastly it is worth mentioning that the SQL query binding is also a capable of indirection. The query itself can be altered by embedding the value of other properties. For example, suppose we logged all of our valve's flow rates to a table using FactorySQL. We could use a query binding like this to calculate the average flow over the last 15 minutes for our current valve:
 SELECT  AVG(Valve{Root Container.ValveNumber}Flow) FROM  ValveFlowHistory WHERE  t_stamp > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 15 MINUTE) 

Window Parameters

Putting indirect designs like those described above into popup windows is a great way to maximize the benefit of indirection. By passing the ValveNumber into a popup window, we can re-use the same window across our entire project simply by altering the valve number that we pass to the popup window. Passing parameters to windows is simple. Any dynamic property on the root container of a window can be used as a window parameter. On a button or other control that opens the window, simply check the "Pass Parameters" checkbox of the Open/Swap Navigation action. Type the name of the dynamic property in the window that you're opening (case sensitive!), and enter a value, for our example a valve number between 1 and 35. That's it! When the window is opened, its ValveNumber property will be set to the appropriate value and the bindings will target the correct valve.