Custom Property Loader Plugins in TestStand
This was going to be part of a series but unfortunately, as mentioned below, there was a lack of available documentation and I ended up implementing a workaround – it was a much simpler solution that could be easily tested. I created an action step which pulled the limits/parameters from the database and wrote them to a temporary CSV file which is then loaded by a Property Loader step. I’d probably only suggest implementing custom plugins at this stage if you were releasing/selling an addon/customisation for TestStand where it would make the time investment worthwhile. Of course, hopefully in TS2017 the documentation will be available to make the process much easier.
In this series of blog posts, I’m going to be talking about how to create a Custom Property Loader Plugin for TestStand using LabVIEW.
I have a custom database schema that doesn’t follow the NI database format that the built-in property loader plugin supports. We have separate tables for limits/test configuration parameters and options for product/test specific limits/parameters. In the last few years, NI has changed aspects of the TestStand Engine to allow more customisation of the various aspects by the use of plugins (e.g. process model plugins, report generation, property loader plugins). The advantage of using a custom property loader plugin is that it allows us to use our custom limits/parameters database but also use the other built-in options as an alternative (e.g. for off-site use at a contract manufacturer without access to the database).
Unfortunately, I couldn’t find much documentation on the subject (NI says that the documentation is coming for TestStand 2017) so figured I’d suffer through the hard work and post it so you know what to expect if you intend on creating custom property loader plugins for TestStand.
For the first part of the series, I’ll start by giving an overview of what a property loader is (and what it does), why you should use it, how to create a custom plugin from the template and give an overview/reference of the VIs / ActiveX objects that make up a custom property loader plugin. In subsequent parts, I’ll be building up my plugin by modifying the VIs to talk to my custom database schema (and the challenges that may come along with it).
Our custom property loader plugin will be talking to a database – but the process should be similar for files – just replace any instance where I’m referencing a database with your custom file IO.
For reference, I’m running TestStand 2016 SP1 and LabVIEW 2017.
Loading Properties in TestStand
Before going into the details of creating a custom property loader plugin (CPLP?! CPP?!) I wanted to just give a quick overview of the various components/mechanisms of loading properties in TestStand.
The main use case for a property loader is to load your test limits and/or test parameters from a file or database at run-time. This gives you the following benefits:
- You can modify/update limits without modifying the sequence files (of course, you need an appropriate change management system)
- All of the limits/parameters are in a single location (e.g. a file/database table rather than having to check individual sequences/steps) – this makes checking/validating/updating the limits/parameters easier
- You can load different sets of limits depending on certain conditions – by specifying the file by expression, you can use different sets of limits/parameters depending on the UUT being tested (e.g. similar products in the same family but with different characteristics)
- Using a centralised database or network-shared file for the properties means that all test stations use the same limits for testing
Natively, TestStand supports comma-separated (.csv), Excel and tab-delimited text (.txt) files and loading properties from an NI TestStand database schema. There’s plenty of information online and in the TestStand training materials about using the built-in plugins (e.g. here, here and here).
The property loader can import any property to just about any TestStand component (that has properties) – the most useful ones are step properties (e.g. to set limits) and sequence variables (e.g. sequence/sub-sequence Locals, StationGlobals etc.). You can also use aliases so that your parameters/limits have sensible names and then these are automatically mapped to the appropriate steps/properties in your sequence.
There are two ways to use property loaders – a property loader step in a test sequence and using the import/export properties dialog in the TestStand tools menu.
It is important to mention this because our custom property loader plugin will not only load and apply properties from the database, but it should also work with the import/export properties dialog as well.
Property Loader Step
The Property Loader Step in TestStand allows you to load properties at sequence/execution run-time by dropping a Property Loader step into your sequence and configuring it on the Step Settings and Source Settings panes of the Step Settings.
Import/Export Properties Dialog
You can also use the import/export properties dialog to manually import/export properties to/from a property loader source. This is useful for generating the initial source data in the correct format (e.g. set the properties in the TestStand environment, export and then load the data in the property loader step) and for verifying the source data. You also use the Export function of the dialog to generate an aliases file (.pla).
As with the Property Loader Step type, you can select the Source for the properties and configure whether to load all of the properties, or just select properties (using the Property Selector pane).
Creating A Custom Property Loader Plugin
The only documentation I could find on creating custom property loader plugins was this small snippet of information which says to copy one of the existing template plugins as the starting point and go from there. So I guess we’ll just dive in then…
Duplicating the Template Plugin
Shipping with TestStand 2016 SP1 is a selection of sample plugins for various programming languages/environments (CVI, .NET, VisualStudio and LabVIEW). You can find these in <TestStand Install Directory>\Components\PropertyLoader\Templates (i.e. C:\Program Files (x86)\National Instruments\TestStand 2016\Components\PropertyLoader\Templates).
The documentation says to copy the template plugin to <TestStand Public>\Components\PropertyLoader\<YourPluginName> directory – initially I couldn’t get the plugin to load following these steps and after a support request with NI it seems that you have to copy and rename the template .llb file to <TestStand Public>\Components\PropertyLoader\ (i.e. C:\Users\Public\Documents\National Instruments\TestStand 2016 (32-bit)\Components\PropertyLoader\MyPlugin.llb) rather than having it reside in a sub-folder. The PropertyLoader folder in <TestStand Public>\Components probably won’t exist if this is your first attempt at a custom plugin – so you’ll need to create it.
You’ll end up with something like this:
The next step is to configure our new plugin by modifying the PluginInformation.vi inside our fresh plugin .llb file:
The VIs themselves are reasonably well documented (most of them are empty stubs though) – here we need to set up the basic information (some fields only apply when loading files e.g. ‘extension’) for TestStand to identify it. You need to change the ID (by default it’s a GUID but I think you can use anything as long as it’s going to be unique to your plugin).
The ‘Type’ field has the following options which are fairly self-explanatory:
- SourceType_Database: When you choose this, the Step Settings for the property loader step allows you to specify/configure a database connection
- SourceType_File: As above, but it prompts you for a file path to the file containing your properties
- SourceType_Custom: I tried to set the enum to SourceType_Custom to see what happened but it just produced an error in TestStand (see below) so I’m not sure if there’s something else that needs to be configured/set first to get this one to work. I guess you’d use this for anything that isn’t a file or a database? Ideas on a postcard please!
After populating the fields and launching TestStand, you can then drop a Property Loader step into your sequence and you should see your newly created plugin in the Source Type drop-down:
Of course, at this point it doesn’t do anything but we’ve at least managed to get it to load and register the plugin. Time for a beer (or other beverage of your choosing)! Next we’ll take a deeper look at what’s inside the template plugin.
Exploring the Template Plugin
Opening up the .llb of the plugin we’ve just created, we find the following VIs:
I’ve already discussed the PluginInformation.vi which sets the metadata/information about the plugin that TestStand uses to populate the plugin in the source type drop down box.
Let’s take a look at the VIs in the template plugin and their functionality…
Custom Property Loader Plugin VIs
|BrowsePropertyLoaderSource.vi||If ‘SupportsBrowseSource’ is set in OverrideOptions (see below), this VI is called when the user clicks the ‘Browse Source’ button – for files this could launch a file dialog or for a database it could be to select a specific set of tables.|
Called when you select the ‘Configure’ button on ‘Plugin Options’ (see below). You could use this VI to launch a dialog where the user can set/configure any plugin specific options for import/export. This is similar to creating a LabVIEW dialog for configuring a custom step type.
|DisplayPluginSpecificOptionsHelp.vi||Called when the user hits the ‘Help’ button in ‘Plugin Options’ (see ConfigurePluginSpecificOptions.vi description).|
|Export.vi||Used when a property loader ‘Export’ is called from the import/export dialog – this is the main VI that exports the current property values back to the property loader source (e.g. file/database). If ‘OverrideImportExportSummary’ is set, then you can also return a custom summary text to display the status of the export operation.|
|ExportAlias.vi||The reverse of ImportAlias.vi (see below) – if you have the ‘OverrideAlias’ set then this can be used to perform an export of the aliases to a custom aliases format. By default, you configure aliases from the Import/Export Properties dialog and these are then automatically exported (as an XML .pla file) when you perform the export.|
|GetImportPropertyItems.vi||Called before Import.vi to read the source and retrieve only the property loader groups information and the properties within that group. This data is used when importing all of the source data (so the plugin knows which properties to load i.e. all of them), determining if a property exists in the source, populating the property selector (for the import/export dialog) and for specifying the properties for the Import operation.|
|Import.vi||Used when a property loader ‘Import’ is called (either through property loader step or the import/export dialog) – this is the main VI that retrieves the properties from the file/database to apply them to the steps/sequence properties. If ‘OverrideImportExportSummary’ is set, then you can also return a custom summary text to display the status of the import operation.|
|ImportAlias.vi||If ‘OverrideAlias’ is set in OverrideOptions (see below), this VI allows you to write custom behaviour for loading the alias names. Aliases allow you to match up variable/parameter names in your property loader source with their matching counterpart in the test sequence (e.g. variable/property name) – there’s documentation and an example of using aliases here. Overriding the default functionality allows you to load/configure aliases as part of your custom plugin (e.g. generate them dynamically or from your property source), rather than specifying them in an aliases file (.pla).|
|OverrideOptions.vi||Used to set override flags/options which control certain options for the plugin (e.g. to allow the user to view the source data and browse for the source). The list of options/overrides are detailed in the ActiveX reference below.|
|PluginInformation.vi||Defines the basic metadata about the plugin when it’s loaded into TestStand (e.g. name, description, type, plugin ID).|
|PluginSpecificOptions.vi||Creates/initialises the available plugin specific options.|
|PluginSpecificOptionsSummary.vi||Generates a summary text of the plugin specific options as shown in ‘Plugin Options’ (see ConfigurePluginSpecificOptions.vi description).|
|PropertyLoaderSourceFormatCount.vi||Specifies the number of different source types that the plugin supports. I’m not quite sure what this means and the template plugin returns 1 (i.e. the plugin supports one source type). I’m not sure if this means that a single plugin can support multiple types (but it’s not obvious how to specify them) – maybe this is reserved for future use?|
|ValidateImport.vi||Called by the Sequence Analyser to allow the creation of a custom VI to check the status of the source during sequence analysis. This could be to check for a correctly configured database connection, check properties are available etc. and return an error if the analysis fails.|
|ViewPropertyLoaderSource.vi||Used to launch a dialog to ‘browse’ the source data (e.g. view the source file, browse database tables).|
Custom Property Loader Plugin ActiveX Components
The VIs all interact using ActiveX methods/properties (as with any other custom LabVIEW components for TestStand), here is a brief overview of the main ones that are used in the VIs.
|PropertyLoader.PropertyLoaderContext||A reference to the instance of the property loader containing generic configuration parameters for the instance and references to the TS Engine and Sequence (i.e. the location of the PropertyLoader).||AliasLocation
|PluginSpecificOptions (PropertyObject)||PropertyObject containing the plugin specific options.||(See TS.PropertyObject)||(See TS.PropertyObject)|
|PropertyLoader.SequenceFileLoader||Contains the list of properties to import which are then updated with the property objects once loaded.||AliasNames
|PropertyLoader.ImportOptions||Contains the user-configured options for the import operation.||ImportAllDataFromSource
|PropertyLoader.ImportPropertyItems||Container for the list of properties in the property source.||Count||Clear
|PropertyLoader.PropertySourceGroups||Container for the list of groups in the property source.||Count||Clear
|PropertyLoader.AliasNames||Contains the aliases used for the import/export operation – used when overriding the default plugin alias functionality (using OverrideAlias).||Count||Clear
|PropertyLoader.OverrideOptions||Contains the options for overriding/enabling certain functionality for the custom plugin.||OverrideAlias
|PropertyLoader.PropertyLoaderPluginInfo||Contains the basic metadata about the plugin.||Description
|PropertyLoader.ExportOptions||Contains options for exporting properties to the source.||StepIdUniqueLookup||N/A|
That’s enough for Part One. I’ve covered an overview of how Property Loaders work, why you would want to create a custom plugin and how to create your very own custom property plugin and load it into TestStand. I’ve also provided some reference material about the VIs and ActiveX objects that make up a custom plugin. In Part 2, I’ll begin customising the VIs to work with a custom database schema.
MediaMongrels Ltd Custom TestStand Solutions
If you’re looking for a bespoke test system and are considering using TestStand, why not get in touch and see if MediaMongrels Ltd can help. We are an NI Alliance Partner with Certified TestStand Developers and we have experience of architecting test systems from the ground up (including custom process models, Operator UIs, custom database recording) to provide flexible and configurable test frameworks for your component and system tests.
Very good overview. Looking forward to Part II. I am currently working on a custom property loader database schema. Do you have a timeframe for Part II article?
Unfortunately I don’t think I’ll be doing a Part 2 – I ran into some problems with the lack of documentation and not being able to debug anything very easily so ended up having to settle for a workaround. What I did was to create a VI which pulls the limits from the database and writes them to a temporary CSV file – this file is then loaded by a PropertyLoader step.