There are rules that must be obeyed when you are creating new tag template modules. For your convenience, these rules have been grouped by topic below.
Tag Template Module Rules for Parameters
The formal parameters for your tag template module must match the fields in the tag type's corresponding table in the tag properties database ("points.mdb") one-for-one.
The names of the first three parameters for all tag template modules must always be: "Name", "Area", and "Description".
In versions of VTS prior to 7.1, there was a 100 parameter ceiling for custom tag template modules. This limit has been removed and an unlimited number of tag parameters may be defined. It should be noted however, that child tags have a 256 parameter limit.
Do not use the period character (.) in the names of any of the fields in the table corresponding to your tag type template (in the tag properties database). Periods are converted to a number hatch, and will prevent data from being written to the database.
Tag Template Module Rules for Subroutines, Modules, and Variables
All references to tag values are passed in as text strings; these text strings must be converted to object values for use by the code within the tag template module. This conversion may be done by using the code syntax displayed below whenever the tag is required.
Scope(\Code, TagName)
An alternative piece of code converts the text string to the object value once. This code must be continuously running in a state so that any user modifications to the tag's parameters from a tag properties dialog can be correctly handled. The code syntax is displayed below.
If ValueType(TagName) == 4 { Text Value };
[
TagName = Scope(\Code, TagName);
]
A variable named, "Root" should be defined in the tag template module, and must be set to the instance of the module. The code below displays the correct syntax.
Root = Self();
The Root variable allows access to the instance value of the tag by the tag's configuration modules.
A variable named, "Value" is common for most tags. It typically holds a numeric value for the tag.
A module named, "ConfigFolder" must be defined to handle the drawing of the contents of the tabbed tag properties folder that enables users to configure the properties of tags belonging to this tag type while the application is running. The ConfigFolder module has two parameters:
Parms A pointer to an array that contains the initial values of the tag's parameters, and that will be modified to contain the values entered by the user while using the tag properties dialog.
Current The current, selected tab number (starting at 0 (ID tab)).
The ConfigFolder module is configured with one state per tab on the tag properties dialog. The tabs contain sets of the tag type's parameters organized into logically consistent groups. When the user clicks on a tab, the value of the "Current" parameter (see above) changes to reflect the index of the selected tab, and the ConfigFolder module changes states to draw new data entry fields on the active tab of the tag properties folder.
The data entry fields on each tab of the tag properties folder are drawn primarily with a set of tools that are contained in a module named, "DialogLibrary". These tools enable you to draw text and numeric entry fields, drop-down lists, and radio buttons. These tools are discussed further in Dialog Library Tools.
When defining the labels to appear on the tabs of the tag properties folder for your custom tag type, first define a list of class 1 variables that refer to a set of tab name variables to be found in the application's Config.ini configuration file. The order of these variables should be the order in which the tabs are displayed in the tag properties folder. Each class 1 variable should be provided with a default value; therefore, if there is no corresponding value set in the application's Config.ini file, this default value can be used for the tab label. Note: The class 1 variables do not directly represent the text label to be displayed on each tab; rather, the Config.ini variables they reference contain the text labels for the tabs. This organization allows you to later translate the labels into another language, or otherwise modify their text without having to change the application's code.
Any tag template that has a value (such as an input tag) must call this variable "Value". This Value variable must not be set in a statement, and must be set in a script subject to the state of the ExternalValue variable (as described below). The setting of the value might use code similar to that shown below:
If Watch(0, Bit1, Bit2) && ! PickValid(ScanInhibit, 0) && !
ExternalValue;
[
Value = 2 * Bit1 + Bit0;
]
The "ExternalValue" variable must be defined in a tag template module with a default value of 0 for tags that have a value. The ExternalValue variable must be used to prevent setting of the Value variable when true. Tag scripts that want to set the Value variable using some algorithm other than the standard one for the tag can set this variable to 1, and then set the Value variable in the script module.
A module called "Common" must be defined within the tag. The Common module handles all of the common drawing object functions that are implemented in the graphic drawing modules. These functions typically include a call to the Navigator module, the PostIt module, and the PkTrend module, as well as calls to code for control dialog boxes. Any external graphic modules must make a call to the Common module within the tag. The Common module takes four parameters that define the area of the screen occupied by the drawing object. The four parameters of the Common module are:
Left Any numeric expression for the object's left side coordinate.
Bottom Any numeric expression for the object's bottom coordinate.
Right Any numeric expression for the object's right side coordinate.
Top Any numeric expression for the object's top coordinate.
If it exists, a subroutine named "Refresh" is called within the tag when the user modifies the tag's parameters using the tag properties folder. The "Refresh" subroutine is called whenever the parameters for the module are changed, and allows the tag to perform any necessary actions to undo any previous actions (such as changing drivers). "Refresh" is called prior to the tag's data being written to the tag properties database. It is passed an array of the previous parameter values for the tag. The current parameter values for the tag have already been changed by the time the "Refresh" module has been called. "Refresh" provides a way to reduce the memory requirements of the tag by reducing the number of active variable references and code required in the tag's main module, and thereby reduces the amount of memory required for each instance of the tag.
The only parameter for "Refresh" is "Parm". The "Parm" parameter is described below:
Parm A pointer to an array that contains the list of values prior to the user's modifications. The tag's actual parameters will have already changed by the time "Refresh" is called. The "Parm" array can be used to test for changes in the values, and take appropriate action based upon the changes.
Don't use SQL reserved words as the name of the tag template. (Doing so will result in an "illegal syntax" error when you attempt to load the database.)
Add the call to the "\Navigator" in each of the drawing modules so that when the user right clicks upon the object, the shortcut menu opens and enables the end user to modify the parameters of the selected tag. (Information on the Navigator can be found in Navigator Calls (Shortcut Menu)).
Add a "HelpKey" parameter, which will get called from the tag properties folder, or from the shortcut menu. This parameter is a string to pass to the help file. WinHelp is the default help file format, but you may override it in the application's Config.ini configuration file using the HelpEXE variable. The HelpKey parameter must use the name you've configured for the HelpEXE variable. If this variable is not defined in the tag, the tag properties folder does not display a Help button. Information on configuring custom help files for your application appears in Custom Help Systems.
Tag Template Module Rules for Tag Drawing Methods
Drawing modules (modules within the tag that provide a method for displaying the value of the tag on the system pages of your application) must always be declared in the GRAPHICS class (see Variable Classes).
Create a Panel module within any of the tag drawing method modules that have parameters. The Panel module performs a task similar to that of the ConfigFolder module (see number 8 above), except that it is responsible for the editing of the tag drawing method module's parameters, rather than the parameters for the tag as a whole. A Panel module is not required if the tag's drawing method module has no parameters. If a tag drawing method module doesn't have a Panel module, a default parameter configuration dialog box is instantiated when the object is placed on the screen.
The Panel module takes one parameter:
Parms A pointer to an array that contains the initial values of the tag's parameters, and that will be modified to contain the values entered by the user while using the tag properties dialog.
The Parms parameter is handled in the same manner as the first parameter for the ConfigFolder module (please refer to the Dialog Library Tools section for details on how to build this module to create the dialog box). This dialog box differs from the ConfigFolder dialog in that it is not a tabbed dialog box, but it does have a preview window at the bottom to allow users to view an image of how the completed tag drawing method will appear when placed on the system page. The size of the dialog box is automatically determined by calling code in VTS so that it is the minimum sized window that will contain all of the GUI objects used.
If a variable called "AutoConfig" is defined within a Panel module, and is given a default value of 1, the calling code for the Panel module will not actually display a dialog box, but will treat the Panel module as a subroutine to set up the parameters without user input. This can be useful in situations where the drawn object requires a parameter as a unique identifier that is simply a counter assigned to each object displayed.
Use the "\Editing" variable to prevent control actions when the configuration toolbox is open on the screen (i.e. while ToolBoxOn is set to "1"). The \Editing variable is set to true when the configuration toolbox is active and some tool other than the null tool is selected. Preventing control dialogs or other mouse actions from being acted upon when this value is true will prevent unintended control when an object is selected for editing.
If a drawing method for an object is normally invisible, you should use the \Editing variable to display a yellow box around the perimeter of the area so that it can be seen during editing and can be selected.
Inside the drawing module, you may define variables called DrawWidth and DrawHeight that can be used to set the width and height of the object placed on the screen during configuration. This is useful in setting the size of a bitmap that is different than the size given by the GUIBitmap reference box. These variables are typically set in the "Panel" module, according to the current parameters set for the graphic object.
Add a constant definition for "DrawLabel", with a default value to each drawing module. This variable's default value specifies the name of a variable in the Config.ini configuration file that defines the label to place on the drawing object's previews during configuration. If this variable is not present, the drawing module's name is used.
Tag Template Module Rules for Alarms
Start any alarm modules for the tag (if necessary).
Tag Template Module Rules for Data Logging
Any data logged or trended variables must be declared in the tag, with a class in the range of 1 to 5 using the syntax below.
Value (1);
A maximum of 100 variables can be logged, and all variables are logged to the same file for this tag. Any variable that is to be data logged should have a variable class of 1 to 5. The class specifies the data type to log:
Class 1 Bit
Class 2 Unsigned byte
Class 3 16-bit integer
Class 4 32-bit integer
Class 5 Single precision floating point
If there are no variables defined in the above class range, the Value variable will be used and treated as if it were a single precision floating point value.
The variables are recorded in the .DAT file in increasing order of variable class, and alphabetically within the class. Both the data logger and the Trend Manager use this data. If the data is permitted to be trended, but not logged, the module must be added to the TRENDERS group.
An optional module named, "LogFileName" may be defined to set the data logger file name for the standard logger and Trend Manager. If the LogFileName module doesn't exist, the LogFileName module in the system is launched to get the data logger file name. The LogFileName module in the system can be overridden by referencing the custom LogFileName module in the application's AppMod.src file (see AppMod.src Root File for a Standard Application) to provide a new common method for naming log files.
Using a custom LogFileName module enables you to change the name of the logger file for the standard logger and Trend Manager every day, week, or batch. The launched module can be a subroutine that simply sets the name once, or it can remain running to change the name dynamically, based upon time or operating conditions. The subroutine will use far less memory, but provides less flexibility. The standard data logger remembers the names of the files, and works with the Trend Manager to allow users to access this data across several files.
The parameters for the LogFileName module are:
Tag The object value of the tag that called the logger.
FileName A pointer to the variable that will be set to the file name. *FileName is updated whenever necessary by "LogFileName". If the tag becomes invalid (i.e. Valid(FileName) == 0), then the logger has stopped, and the "LogFileName" module must slay itself.
For each data logged value in the LogFileName module, a copy of the Logger module must be launched in a script once the tag is started. The logger takes the following parameters:
Tag The object value of the tag whose data should be logged to disk.
Interval The time interval (in seconds) between logs.
Trigger A pointer to a value that changes state when the data is to be recorded. This can be used to trigger a log on change. Incrementing a counter is a suitable means of triggering this value; optionally, you may point to the actual data value that is to be logged when it changes.
Records The number of records to write to the file.
Buffers The number of records to hold in RAM before writing to disk.
Launching the logger logs all of the class 1 through class 5 variables. It is probably better to use the standard Logger tag to perform this task, rather than code a logger to call into the tag. The logger call uses less RAM, but provides less flexibility, and requires more code maintenance. The advantage of coding the logger call into the module is that the user doesn't have to do any configuration work to get the data logging. Any tags calling the logger module are automatically added to the "Loggers" and "Trenders" tag groups.
To retrieve data from a Logger, the "GetLog" function may be used. "GetLog" handles the accessing of the data by the variable name and data spanning several files. If the data doesn't currently exist, invalid array elements are returned. The first parameter is set to the data array retrieved from the files. When this value becomes valid, "GetLog" has completed. "GetLog" runs multiple threaded data retrievals, so the file access occurs in the background.
The parameters for "GetLog" are:
Result A pointer to the value to set to the array retrieved from file.
Tag The object value of the tag that has logged the data to be accessed.
Name The name of the logged value to access (i.e. class 1 to class 5 variable in the tag). If this value is an empty string (""), the data accessed is the time stamp in number of seconds since January 1, 1970.
Start The start time of the data to access (seconds since midnight, January 1, 1970).
End The end time of the data to access (seconds since midnight, January 1, 1970).
TPP The time period per data point. If this value is not valid, the Size parameter (see below) is used to determine how to access the data.
Size The maximum number of tags to get. If this is a valid value > 0, the data is accessed "one at a time" from the file, rather than at equal time intervals.
Mode The following values can be used for the "Mode" parameter:
0 = Time weighted average
1 = Minimum in range
2 = Maximum in range
3 = Change in value over the range
4 = Value at the start of the range